/*
 *  td.h
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 23/09/2010.
 *
 */


#ifndef _tss_h_
#define _tss_h_

#include "component.h"
#include "commonutil.h"

using namespace std;

class TSS : public Component
{
public:
	double mass;
	double partial_qddotOld;
	double lam;
	double gam;
	double s;
	double theta;
	
	vector<double> qMid;
	vector<double> dqMid;
	double lamMid, gamMid, sMid, thetaMid;
	double fTMid, QMid, hMid;
	
	double denom;
	double toldenom;

	int state;
	
	
//	vector<double> u;				/** Unitary vector conecting points */
	double partial_qdotOld;
	
	double betac;	// thermo-elastic coupling parameter
	double c;
	double c0;	// heat capacity
	double lam0;	// initial spring length
	double c10;	// spring constant 1
	double c11; 	// spring constant 2

	double mu0;	// maxwell spring constant 1
	double mu1;	// maxwell spring constant 2
	double beta0;	
	
	double ppLam;
	double pLam;	// converged lam
	double pGam;	// converged gam
	double pS;	// converged s
	
	double fT;	// Total force
	double Q;	// Viscous force
	double h;	// Heat flux

	double auxd;
	double i, j;

	double t5;
	double t6;
	double t7;
	double t9;
	double t12;
	double t16;
	double t22;
	double t29;
	double t35;
	double t36;
	double t37;
	double t39;
	double t41;
	double t42;
	double t43;
	double t44;
	double t47;
	
	double t4;
	double t8;
	double t10;
	double t13;
	double t15;
	double t20;
	double t24;
	double t28;
	double t32;
	double t33;
	double t46;
	double t51;
	double t52;
	double t53;
	double t56;
	double t57;
	double t60;
	double t61;
	double t64;
	double t65;
	double t67;
	double t68;
	double t69;
	double t70;
	double t72;
	double t73;
	double t74;
	double t76;
	double t78;
	
	double t14;
	double t19;
	double t23;
	double t25;
	double t38;
	double t48;
	double t58;
	double t62;
	double t77;
	
	double t3;
	double t11;

	double t1;
	double t2;
	double t18;
	double t21;
	double t26;
	double t30;
	double t27;
	double t31;
	double t49;
	double t34;
	double t59;
	double t63;
	double t66;
	double t71;
	double t79;
	double t81;
	double t82;
	double t85;
	double t88;
	double t93;
	double t17;
	double t102;
	double t50;
	double t54;
	double t55;
	double t94;
 
	string mode;
	double Q0;
	
/*	Data members from the base class Component
	int dim;
	int numDofs;
	vector<string> pointNames;
	map<string,Point*,less<string> > mPoints;
	vector<int> localGlob;
	double time;
	string matName;
	vector<double> q;
	vector<double> dq;
 	vector<double> qC;
  	vector<double> dqC;
	vector<double> Fi;
	vector<double> Fq;
	vector<double> Ft;
	vector< vector<double> > Ki;
	vector< vector<double> > Kq;
	vector< vector<double> > Kdq;
	vector< vector<double> > M;
	double perturbation;	//For numerical differentiation
	int integratorType;
	double thetab;			// Ambient temperature
*/

public:
	TSS();
	TSS(vector<string>&, vector<double>&, double&, int);
	TSS(vector<string>&, vector<double>&, map<string,string>&,double&, int);
	~TSS(){}

	/** Virtual functions from base */
	void setDofs(void);
	void initializeGlobalDofs(vector<double> &, vector<double> &, const double &);
	void calcFi(const vector<double>&);
	void calcFq(const int&);
	void calcFt(const double&, const double&, const int&);
	void calcKi(double&);
	void calcKq(int);
	void calcKdq(double&);
	void calcM(const vector<double>&, const double &);
	void calcMLumped(const vector<double>&, const double &);
	void setMatAtComp(Material*);
	string getMatName()	{}
	void initializeCompRes(const bool&, const double&, const int&, const bool);
//	void initializeCompTang(const bool&, const bool&);
	void initializeCompTang(const bool&);
	void calcEner(double&, double&, double&, double&, double&, double&, double&, int&, vector<double>&, vector<double>&);
	void calcEntropy(double&, double&);
	void calcAM(vector<double>&, vector<double>&, vector<double>&);
	void updateComp(void);
	void setInitialConditions(vector<double>&, vector<double>&);
	double getTemperature(void);
	void setIniDofs(vector<double>&);
	void calcPhi(const vector<double>&);
	void calcDPhi(const vector<double>&);
	void calcMSmooth(const vector<double>&, const double&);
	void calcFSmooth(const vector<double>&, const vector<double>&, const double&);
	int checkState();
	
	/** Local functions */
//	void makeM();
	double V(double, double, double);			// Potential
	double dlamV(double, double, double);		// Standard partial derivative of V respect to lambda
	double dgamV(double, double, double);		// Standard partial derivative of V respect to gamma
	double dentV(double, double, double);		// Standard partial derivative of V respect to entropy
	double entropy(double, double, double);		// Entropy as a function of length, anelastic displacement and temperature
	double eta(double, double, double);			// Viscosity as a function of length, anelastic displacement and entropy
	double Eta(double);			// Viscosity as a function of temperature
	double integrateGam1ex(double&, double&, double&, double&);	// First-order explicit integration of internal variable gamma (explicit Euler)
	double integrateGam1im(double&,	double&, double&, double&);	// First-order implicit integration of internal variable gamma (implicit Euler)
	double integrateGamMid(double&, double&, double&, double&);	// Second-order implicit integration of internal variable gamma (midpoint)
	double integrateGamTra(double&, double&, double&, double&);	// Second-order implicit integration of internal variable gamma (trapezoidal)
//	double integrateGamCon(double&, double&, double&, double&);	// Consistent implicit integration of internal variable gamma (midpoint)
	double calcLam(vector<double>&);
	double calcGam(double&, double&, double&, double&);		// Integration of internal variable
	void calcLocalKqNumeric();
	double DlamV(double, double, double);		// Discrete partial derivative of V respect to lambda
	double DgamV(double, double, double);		// Discrete partial derivative of V respect to gamma	
	double DentV(double, double, double);	// Discrete partial derivative of V respect to entropy
	double partialVLam(double,double, double);
	double partialVGam(double,double, double);
	double partialVS(double,double, double);

	
	/** Friend functions */
	friend double lTwoNorm(const vector<double>& v1);
	friend double lTwoNorm(const vector<double>& v1, const vector<double>& v2);
	friend void uVersor(const vector<double>& v1, const vector<double>& v2, const double & dis, vector<double>& u);
	friend void printSTLVector(vector<double>& v);
	friend void printSTLMatrix(const vector< vector<double> >& m);
};

#endif

